package com.wzdigit.wms.wms.service.core;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.InvLoc;
import com.wzdigit.wms.basic.domain.transfer.DocPreAloc;
import com.wzdigit.wms.basic.mapper.core.inventory.InvLocMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.LotnoMapper;
import com.wzdigit.wms.basic.service.code.InventoryService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 库位级别库存信息 服务类
 *
 * @author yangdongjie
 * @ZoneAttrService.java
 * @2021年1月4日上午11:16:31
 */
@Service
@Slf4j
public class InvLocService {

    @Autowired
    private LotnoMapper lotnoMapper;

    @Autowired
    private InvLocMapper invLocMapper;
    
    @Autowired
    private InventoryService inventoryService;

    private final Lock lock = new ReentrantLock();

    /**
     * 获取可用库存
     *
     * @param dto
     * @return
     * @throws Exception
     */
    /*public List<InvLoc> getEffectiveInvLocDto(GetEffectiveInvLocDto dto) throws Exception {
        QueryWrapper<Lotno> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("CUSTOMER_ID", dto.getCustomerId());
        queryWrapper.eq("SKU_ID", dto.getSkuId());
        WrapperUtils.queryWrapperLotAttr(dto, queryWrapper);
        Lotno lotno = lotnoMapper.selectOne(queryWrapper);
        if (lotno == null) {
            return null;
        }
        QueryWrapper<InvLoc> invLocQueryWrapper = new QueryWrapper<>();
        invLocQueryWrapper.eq("WHS_ID", dto.getWhsId());
        invLocQueryWrapper.eq("OWNER", dto.getCustomerId());
        invLocQueryWrapper.eq("SKU_ID", dto.getSkuId());
        invLocQueryWrapper.eq("FACTORY", dto.getFactory());
        invLocQueryWrapper.eq("VENDOR_ID", dto.getVendorId());
        invLocQueryWrapper.eq("LOTNO", lotno.getLotno());
        invLocQueryWrapper.eq("INV_ATTR", dto.getInvAttr());
        invLocQueryWrapper.eq("QA_STATUS", dto.getQaStatus());
        return invLocMapper.selectList(invLocQueryWrapper);
    }*/

    /**
     * 根据仓库ID和SKU查询
     *
     * @param toWhs
     * @param fmSku
     * @return
     */
    public InvLoc selectByWhsAndSku(Integer toWhs, Integer fmSku) {

        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        wrapper.eq("WHS_ID", toWhs).eq("SKU_ID", fmSku);
        InvLoc invLoc = invLocMapper.selectOne(wrapper);
        return invLoc;
    }


    /**
     * 根据主键和数量更新
     *
     * @param invLocId
     * @param preInQty
     */
    public void updateByPkAndInQty(Integer invLocId, BigDecimal preInQty) {

        lock.lock();
        Integer row = new Integer(0);
        try {
            InvLoc invLoc = new InvLoc();
            invLoc.setPreInQty(preInQty).setInvLocId(invLocId);
            row = invLocMapper.updateById(invLoc);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        log.info("成功更新{}条记录", row);
    }

    /**
     * 根据仓库查询
     *
     * @param fmWhs
     * @return
     */
    public List<InvLoc> selectByWhsId(Integer fmWhs) {
        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        wrapper.eq("WHS_ID", fmWhs);
        List<InvLoc> invLocList = invLocMapper.selectList(wrapper);
        return invLocList;
    }

    /**
     * 根据库位ID集合和批次号查询库位库存
     *
     * @param locIdList
     * @param lotno
     * @return
     */
    public List<InvLoc> selectByLocIdListAnLotno(List<Integer> locIdList, String lotno) {

        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        wrapper.in("LOC_ID", locIdList).eq("LOTNO", lotno);
        List<InvLoc> invLocList = invLocMapper.selectList(wrapper);
        return invLocList;
    }

    /**
     * 根据库位ID和批次号查询库位库存
     *
     * @param locId
     * @param lotno
     * @return
     */
    public InvLoc selectByLocIdAnLotno(Integer locId, String lotno) {

        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        wrapper.eq("LOC_ID", locId).eq("LOTNO", lotno);
        InvLoc invLoc = invLocMapper.selectOne(wrapper);
        return invLoc;
    }

    /**
     * 根据实体更新库位库存
     *
     * @param invLocUpdate
     * @return
     */
    /*public Integer updateAlocQtyByInvLocId(InvLoc invLocUpdate) {

        lock.lock();
        Integer row = new Integer(0);
        try {
            row = invLocMapper.updateAlocQtyByInvLocId(invLocUpdate);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return row;
    }*/

    /**
     * @param whsId
     * @param lotno
     * @return
     */
    public List<InvLoc> selectByWhsIdAnLotno(Integer whsId, String lotno) {

        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        wrapper.eq("WHS_ID", whsId);
        wrapper.eq("LOTNO", lotno);
        wrapper.isNull("LOC_ID");


        List<InvLoc> invLoc = invLocMapper.selectList(wrapper);
        return invLoc;
    }

    /**
     * 获取GOODS对应库存
     */
//    public List<InvLoc> getEffectiveInvLoc(Goods goods) {
    public InvLoc getEffectiveInvLoc(Goods goods) {

        QueryWrapper<InvLoc> invLocQueryWrapper = new QueryWrapper<>();

        //WHS_ID
        if (goods.getLocId() == null) {
            invLocQueryWrapper.isNull("LOC_ID");
        } else {
            invLocQueryWrapper.eq("LOC_ID", goods.getLocId());
        }
        //WHS_ID
        if (goods.getWhsId() == null) {
            invLocQueryWrapper.isNull("WHS_ID");
        } else {
            invLocQueryWrapper.eq("WHS_ID", goods.getWhsId());
        }
        //OWNER
        if (goods.getOwner() == null) {
            invLocQueryWrapper.isNull("OWNER");
        } else {
            invLocQueryWrapper.eq("OWNER", goods.getOwner());
        }
        //SKU_ID
        if (goods.getSkuId() == null) {
            invLocQueryWrapper.isNull("SKU_ID");
        } else {
            invLocQueryWrapper.eq("SKU_ID", goods.getSkuId());
        }
        //FACTORY
        if (goods.getFactory() == null) {
            invLocQueryWrapper.isNull("FACTORY");
        } else {
            invLocQueryWrapper.eq("FACTORY", goods.getFactory());
        }
        //VENDOR_ID
        if (goods.getVendorId() == null) {
            invLocQueryWrapper.isNull("VENDOR_ID");
        } else {
            invLocQueryWrapper.eq("VENDOR_ID", goods.getVendorId());
        }
        //LOTNO
        if (goods.getLotno() == null) {
            invLocQueryWrapper.isNull("LOTNO");
        } else {
            invLocQueryWrapper.eq("LOTNO", goods.getLotno());
        }
        //INV_ATTR
        if (goods.getInvAttr() == null) {
            invLocQueryWrapper.isNull("INV_ATTR");
        } else {
            invLocQueryWrapper.eq("INV_ATTR", goods.getInvAttr());
        }
        //QA_STATUS
        if (goods.getQaStatus() == null) {
            invLocQueryWrapper.isNull("QA_STATUS");
        } else {
            invLocQueryWrapper.eq("QA_STATUS", goods.getQaStatus());
        }

//        List<InvLoc> invLocs = invLocMapper.selectList(invLocQueryWrapper);
        InvLoc invLoc = invLocMapper.selectOne(invLocQueryWrapper);
        return invLoc;
    }

    /**
     * 根据库位ID集合,批次号,组织查询库位库存
     *
     * @param locIdList
     * @param gdnPreAloc
     * @return
     */
    public List<InvLoc> selectByLocIdListAnLotnoAndFatory(List<Integer> locIdList, DocPreAloc gdnPreAloc) {

        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
//        wrapper.in("LOC_ID", locIdList).eq("LOTNO", lotno).eq("FACTORY",factory );



        wrapper.eq("WHS_ID", gdnPreAloc.getWhsId());
        wrapper.eq("OWNER", gdnPreAloc.getOwner());
        wrapper.eq("SKU_ID", gdnPreAloc.getSkuId());


        //----------------------------------------------------------------------------
//        wrapper.isNull(gdnPreAloc.getWhsId() == null, "WHS_ID");
//        wrapper.eq(!(gdnPreAloc.getWhsId() == null), "WHS_ID", gdnPreAloc.getWhsId());
//
//        wrapper.isNull(gdnPreAloc.getOwner() == null, "OWNER");
//        wrapper.eq(!(gdnPreAloc.getOwner() == null), "OWNER", gdnPreAloc.getOwner());
//
//        wrapper.isNull(gdnPreAloc.getSkuId() == null, "SKU_ID");
//        wrapper.eq(!(gdnPreAloc.getSkuId() == null), "SKU_ID", gdnPreAloc.getSkuId());
        //----------------------------------------------------------------------------


        wrapper.isNull(gdnPreAloc.getFactory() == null, "FACTORY");
        wrapper.eq(!(gdnPreAloc.getFactory() == null), "FACTORY", gdnPreAloc.getFactory());

        wrapper.isNull(gdnPreAloc.getVendorId() == null, "VENDOR_ID");
        wrapper.eq(!(gdnPreAloc.getVendorId() == null), "VENDOR_ID", gdnPreAloc.getVendorId());

        wrapper.isNull(gdnPreAloc.getLotno() == null, "LOTNO");
        wrapper.eq(!(gdnPreAloc.getLotno() == null), "LOTNO", gdnPreAloc.getLotno());

        wrapper.isNull(gdnPreAloc.getInvAttr() == null, "INV_ATTR");
        wrapper.eq(!(gdnPreAloc.getInvAttr() == null), "INV_ATTR", gdnPreAloc.getInvAttr());

        wrapper.isNull(gdnPreAloc.getQaStatus() == null, "QA_STATUS");
        wrapper.eq(!(gdnPreAloc.getQaStatus() == null), "QA_STATUS", gdnPreAloc.getQaStatus());


        if (locIdList == null) {
            wrapper.isNull("LOC_ID");
        } else if (locIdList != null && locIdList.size() > 0) {
            wrapper.in("LOC_ID", locIdList);
        }




        List<InvLoc> invLocList = invLocMapper.selectList(wrapper);
        return invLocList;
    }


    public List<InvLoc> selectListByWhsId(Integer whsId) {

        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();

        wrapper.isNull(whsId == null, "WHS_ID");
        wrapper.eq(!(whsId == null), "WHS_ID", whsId);

        List<InvLoc> invLocList = invLocMapper.selectList(wrapper);
        return invLocList;
    }

    /**
     * 查询那些【未上架】的库位库存,故没有库位
     *
     * @param whsId
     * @param lotno
     * @param factory
     * @return
     */
    public List<InvLoc> selectByWhsIdAnLotnoAndFactory(Integer whsId, String lotno, String factory) {
        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        wrapper.eq("WHS_ID", whsId);
        wrapper.eq("LOTNO", lotno);
        wrapper.isNull("LOC_ID");
        wrapper.eq("FACTORY", factory);

        List<InvLoc> invLoc = invLocMapper.selectList(wrapper);
        return invLoc;
    }
    
    /*@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateQaStatus(SearchInvRequest dto, Integer qtySize, Integer qaStatus, String modifyUser) {
    	UpdateInvLocQtyDto input = new UpdateInvLocQtyDto();
    	input.setOperator(modifyUser);
    	
    	// 更新原值库存值
    	List<InvLoc> invLocList = getEffectiveInvLoc(dto);
    	if(invLocList.size() > 0) {
    		// 变更数量
    		BigDecimal qtyBigDecimal = new BigDecimal(qtySize);
    		for (InvLoc invLoc : invLocList) {
        		if(qtyBigDecimal.signum() == 0) {
        			break;
        		}
        		
        		// 库存数量
        		BigDecimal qty = invLoc.getQty();
        		if(qty.compareTo(qtyBigDecimal) == -1) {
        			// 库存 < 变更
        			input.setQty(qty.negate());
        			qtyBigDecimal = qtyBigDecimal.subtract(qty);
        		} else {
        			// 库存 >= 变更
        			input.setQty(qtyBigDecimal.negate());
        			qtyBigDecimal = BigDecimal.ZERO;
        		}
        		input.setInvLocId(invLoc.getInvLocId());
        		inventoryService.updateInvLocQty(input);
    		}
    	}
    	
    	// 更新新值库存值
    	dto.setQaStatus(qaStatus);
    	invLocList = getEffectiveInvLoc(dto);
    	if(invLocList.size() > 0) {
    		input.setQty(new BigDecimal(qtySize));
    		input.setInvLocId(invLocList.get(0).getInvLocId());
    		inventoryService.updateInvLocQty(input);
    	} else {
    		InvLoc invLoc = new InvLoc();
    		invLoc.setWhsId(dto.getWhsId());
    		invLoc.setLocId(dto.getLocId());
    		invLoc.setFactory(dto.getFactory());
    		invLoc.setOwner(dto.getOwnerId());
    		invLoc.setSkuId(dto.getSkuId());
    		invLoc.setInvAttr(dto.getInvAttr());
    		invLoc.setLotno(dto.getLotno());
    		invLoc.setVendorId(dto.getVendorId());
    		invLoc.setQaStatus(qaStatus);
    		invLoc.setUnit(dto.getUnit());
    		invLoc.setQty(new BigDecimal(qtySize));
    		invLoc.setCreateTime(new Date());
    		invLoc.setCreateUser(modifyUser);
    		invLocMapper.insert(invLoc);
    	}
    }*/

    public InvLoc selectByGoods(Goods goods) {
        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        //仓库ID
        if (goods.getWhsId() == null) {
            wrapper.isNull("WHS_ID");
        }else {
            wrapper.eq("WHS_ID", goods.getWhsId());
        }
        //货主
        if (goods.getOwner() == null) {
            wrapper.isNull("OWNER");
        }else {
            wrapper.eq("OWNER", goods.getOwner());
        }
        //sku_id
        if (goods.getSkuId()==null) {
            wrapper.isNull("SKU_ID");
        }else {
            wrapper.eq("SKU_ID", goods.getSkuId());
        }
        //工厂
        if (goods.getFactory() == null) {
            wrapper.isNull("FACTORY");
        }else {
            wrapper.eq("FACTORY", goods.getFactory());
        }
        //供应商
        if (goods.getVendorId() == null) {
            wrapper.isNull("VENDOR_ID");
        }else {
            wrapper.eq("VENDOR_ID", goods.getVendorId());
        }
        //库存性质
        if (goods.getInvAttr()==null) {
            wrapper.isNull("INV_ATTR");
        }else {
            wrapper.eq("INV_ATTR", goods.getInvAttr());
        }
        //品质状态
        if (goods.getQaStatus()==null) {
            wrapper.isNull("QA_STATUS");
        }else {
            wrapper.eq("QA_STATUS", goods.getQaStatus());
        }
        //批次属性
        if (goods.getLotno() ==null) {
            wrapper.isNull("LOTNO");
        }else {
            wrapper.eq("LOTNO", goods.getLotno());
        }
        //locid
        if (goods.getLocId() == null) {
            wrapper.isNull("LOC_ID");
        }else {
            wrapper.eq("LOC_ID", goods.getLocId());
        }



        InvLoc invLoc = invLocMapper.selectOne(wrapper);
        return invLoc;
    }
    
    /*public List<InvLoc> getEffectiveInvLoc(SearchInvRequest dto) {
        //创建类型的条件构造器
        QueryWrapper<InvLoc> wrapper = new QueryWrapper<>();
        //LOC_ID
        if (dto.getLocId() == null) {
            wrapper.isNull("LOC_ID");
        } else {
            wrapper.eq("LOC_ID", dto.getLocId());
        }
        //WHS_ID
        if (dto.getWhsId() == null) {
            wrapper.isNull("WHS_ID");
        } else {
            wrapper.eq("WHS_ID", dto.getWhsId());
        }
        //OWNER
        if (dto.getOwnerId() == null) {
            wrapper.isNull("OWNER");
        } else {
            wrapper.eq("OWNER", dto.getOwnerId());
        }
        //SKU_ID
        if (dto.getSkuId() == null) {
            wrapper.isNull("SKU_ID");
        } else {
            wrapper.eq("SKU_ID", dto.getSkuId());
        }
        //FACTORY
        if (dto.getFactory() == null) {
            wrapper.isNull("FACTORY");
        } else {
            wrapper.eq("FACTORY", dto.getFactory());
        }
        //VENDOR_ID
        if (dto.getVendorId() == null) {
            wrapper.isNull("VENDOR_ID");
        } else {
            wrapper.eq("VENDOR_ID", dto.getVendorId());
        }
        //LOTNO
        if (dto.getLotno() == null) {
            wrapper.isNull("LOTNO");
        } else {
            wrapper.eq("LOTNO", dto.getLotno());
        }
        //INV_ATTR
        if (dto.getInvAttr() == null) {
            wrapper.isNull("INV_ATTR");
        } else {
            wrapper.eq("INV_ATTR", dto.getInvAttr());
        }
        //QA_STATUS
        if (dto.getQaStatus() == null) {
            wrapper.isNull("QA_STATUS");
        } else {
            wrapper.eq("QA_STATUS", dto.getQaStatus());
        }
        wrapper.orderByDesc("QTY");
        wrapper.last("FOR UPDATE");
        List<InvLoc> invLocList = invLocMapper.selectList(wrapper);
        return invLocList;
    }*/
}